#include "pch.h"
#include "sdsky.h"
#include "..\Common\DirectXHelper.h"
#include <mutex>


using namespace sdsky2;
using namespace DX;
using namespace std;
using namespace concurrency;

sdsky::sdsky(sfloat const & interval) :
	m_interval(interval)
{
	Verify(QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER*>(&m_freq)));
}

void sdsky::add(star const & star)
{
	m_stars.push_back(star);
}

void sdsky::clear()
{
	m_stars.clear();
}

void sdsky::update()
{
#if defined(_DEBUG)
	fps();
#endif

	const sfloat& t = m_interval;

	for (auto & s1 : m_stars)
	{
		sfloat Fdx = 0;
		sfloat Fdy = 0;

		sfloat Gm1 = G;		// G * s1.m
		sfloat ttm = t*t;	// t*t/s1.m

		mutex m;

		/*parallel_for_each(cbegin(m_stars), cend(m_stars), [&](star const & s2) {*/
		for_each(cbegin(m_stars), cend(m_stars), [&](star const & s2) {
			if (&s1 != &s2)
			{
				sfloat rx = s2.p.x - s1.p.x;
				sfloat ry = s2.p.y - s1.p.y;
				sfloat rr = rx*rx + ry*ry;
				sfloat r = sqrt(rr);

				sfloat f = Gm1*s2.m / rr;
				sfloat fdx = f*rx / r;
				sfloat fdy = f*ry / r;

				/*m.lock();*/
				Fdx += fdx;
				Fdy += fdy;
				/*m.unlock();*/
			}
		});

		sfloat dvx = Fdx * ttm;
		sfloat dvy = Fdy * ttm;

		s1.v.x += dvx;
		s1.v.y += dvy;
	}

	for (auto & s : m_stars)
	{
		s.p.x += s.v.x * t;
		s.p.y += s.v.y * t;
	}
}

vector<star> const & sdsky::stars()
{
	return m_stars;
}

void sdsky::fps()
{
	long long qpc;
	Verify(QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&qpc)));

	double ellapsed = 1.0 * (qpc - m_lastQpc) / m_freq;

	++m_frames;

	if (ellapsed >= 1.0)
	{
		TRACE(L"sdsky fps: %.0f\n", m_frames / ellapsed);
		m_lastQpc = qpc;
		m_frames = 0;
	}
}